﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Xunit;

namespace DiffuseEnjoyIdle.Test.User
{
    public class Test
    {
        public Person person = new Person();
        [Fact]
        public void Tests()
        {
            person.country = "china";
            Man man = new Man();
            man.name = "张三";
            man.sex = "男";
            person.manList = new List<Man>();
            person.manList.Add(man);
            PrintMessage<Person>(person);
        }

        public static string PrintMessage<T>(T t)
        {
   
            PrintInternal(t); 
            return t.ToString();
        }

        // 传入需要查询的数据结构体，通过反射打印其所有公共属性
        private static void PrintInternal<T>(T t, string intervalStr = "")
        {
            // 通过泛型类T实例的Type获取所有公共属性
            PropertyInfo[] infos = t.GetType().GetProperties();
            foreach (PropertyInfo info in infos)
            {
                if (info != null)
                {
                    // 判断属性类型是否为泛型类型，如：
                    // typeof(int).IsGenericType --> False
                    // typeof(List<int>).IsGenericType --> True
                    // typeof(Dictionary<int>).IsGenericType --> True
                    if (info.PropertyType.IsGenericType)
                    {
                        // 如List<Man>，返回类名Man
                        string className = info.PropertyType.GetGenericArguments()[0].Name;
                       
                        // 因为是反射返回的数据，无法直接转换为List使用，针对这种数据，反射机制对这种属性值提供了
                        // “Count”列表长度、“Item”子元素等属性；
                        object subObj = info.GetValue(t, null);
                        if (subObj != null)
                        {
                            // 获取列表List<Man>长度
                            int count = Convert.ToInt32(subObj.GetType().GetProperty("Count").GetValue(subObj, null));
                            for (int i = 0; i < count; i++)
                            {    // 获取列表子元素Man，然后子元素Man其实也是一个类，然后递归调用当前方法获取类Man的所有公共属性
                                object item = subObj.GetType().GetProperty("Item").GetValue(subObj, new object[] { i });
                                PrintInternal(item, "  ");
                                
                            }
                        }
                    }
                    else
                    {
                        // 属性info，通过info.Name获取属性字段名，通过info.GetValue(t, null)获取值（返回obje类型需要自己转换）
                        
                    }
                }
            }
        }
    }

    public class Person
    {
        public string country;
        public List<Man> manList = new List<Man>();
    }

    public class Man
    {
        public string name;
        public string sex;
    }
}
